home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir27 / calctool.zip / GRAPHICS.C < prev    next >
C/C++ Source or Header  |  1992-09-09  |  11KB  |  373 lines

  1.  
  2. /*  @(#)graphics.c 1.12 89/12/21
  3.  *
  4.  *  These are the independent graphics routines used by calctool.
  5.  *
  6.  *  Copyright (c) Rich Burridge.
  7.  *                Sun Microsystems, Australia - All rights reserved.
  8.  *
  9.  *  Permission is given to distribute these sources, as long as the
  10.  *  copyright messages are not removed, and no monies are exchanged.
  11.  *
  12.  *  No responsibility is taken for any errors or inaccuracies inherent
  13.  *  either to the comments or the code of this program, but if
  14.  *  reported to me then an attempt will be made to fix them.
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <strings.h>
  19. #include "calctool.h"
  20. #include "color.h"
  21. #include "extern.h"
  22.  
  23.  
  24. but_text(row, column, portion, state)
  25. int row, column, portion ;
  26. enum but_state state ;
  27. {
  28.   enum font_type butfont ;
  29.   int i, n ;
  30.  
  31.   n = row*BCOLS*2 + column*2 + portion ;
  32.   if (buttons[n].color == GREY) return ;
  33.   get_label(n) ;
  34.   for (spaces = 0, i = 0; i < strlen(pstr); i++)
  35.     if (pstr[i] == ' ') spaces++ ;
  36.   x = chxoff[spaces] ;
  37.   y = (n & 1) ? 40 : 18 ;
  38.   if (spaces == 3)  y += 4 ;
  39.   butfont = (spaces == 3) ? BFONT : NFONT ;
  40.   if (state == NORMAL)
  41.     color = (!iscolor & portion) ? WHITE : BLACK ;
  42.   if (state == INVERTED)
  43.     color = (portion) ? BLACK : WHITE ;
  44.   drawtext(column*(BWIDTH+BGAP)+BBORDER+x,
  45.        DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+y, KEYCANVAS, butfont, color, pstr) ;
  46. }
  47.  
  48.  
  49. do_repaint()     /* Redraw the calctool canvas[es]. */
  50. {
  51.   make_canvas(0) ;
  52. }
  53.  
  54.  
  55. drawbox(x, y, width, height)
  56. int x, y, width, height ;
  57. {
  58.   drawline(x, y, x+width, y) ;
  59.   drawline(x, y, x, y+height) ;
  60.   drawline(x, y+height, x+width, y+height) ;
  61.   drawline(x+width, y, x+width, y+height) ;
  62. }
  63.  
  64.  
  65. draw_button(row, column, portion, state)
  66. int row, column, portion ;
  67. enum but_state state ;
  68. {
  69.   int n ;
  70.  
  71.   n = row*BCOLS*2 + column*2 + portion ;
  72.   if (!portion)
  73.     {
  74.       color = (iscolor) ? buttons[n].color : WHITE ;
  75.       drawbox(column*(BWIDTH+BGAP)+BBORDER,
  76.               DISPLAY+row*(BHEIGHT+BGAP)+BBORDER, BWIDTH, BHEIGHT) ;
  77.       fillbox(column*(BWIDTH+BGAP)+BBORDER+1,
  78.               DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+1, 42, 50, 1, color) ;
  79.     }
  80.   else
  81.     { 
  82.       drawbox(column*(BWIDTH+BGAP)+BBORDER+5,
  83.               DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+26, 34, 21) ;
  84.       color = (iscolor) ? buttons[n].color : BLACK ;
  85.       fillbox(column*(BWIDTH+BGAP)+BBORDER+6,
  86.               DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+27, 32, 19, 1, color) ;
  87.     }
  88.   but_text(row, column, portion, state) ;
  89. }
  90.  
  91.  
  92. fillbox(x, y, width, height, boundry, color)
  93. int x, y, width, height, boundry, color ;
  94. {
  95.   if (boundry)
  96.     {
  97.       color_area(x, y, width, height, WHITE) ;
  98.       color_area(x+1, y+1, width-2, height-2, color) ;
  99.     } 
  100.   else color_area(x, y, width, height, color) ;
  101. }
  102.  
  103.  
  104. get_menu_value()     /* Get menu value if valid right mouse press. */
  105. {
  106.   int i, n, val ;
  107.  
  108.   n = row*BCOLS*2 + column*2 + portion ;
  109.   for (i = 0; i < MAXMENUS; i++)
  110.     if (buttons[n].value == validmenu[i])
  111.       {
  112.         val = do_menu((enum menu_type) i) ;
  113.         if (val) handle_menu_selection(i, val) ;
  114.         break ;
  115.       }
  116. }
  117.  
  118.  
  119. grey_buttons(base)     /* Grey out numeric buttons depending upon base. */
  120. enum base_type base ;
  121. {
  122.   char val ;
  123.   int column, i, n, portion, row ;
  124.  
  125.   if (gtype == TTY) return ;
  126.   for (i = 0; i < 16; i++)
  127.     {
  128.       val = digits[i] ;
  129.       for (n = 0; n < TITEMS; n++)
  130.         if (val == buttons[n].value) break ;           
  131.       if (i < basevals[(int) base])          
  132.         {                 
  133.           if (i < 10) buttons[n].color = LBLUE ;
  134.           else buttons[n].color = PINK ;
  135.         }  
  136.       else buttons[n].color = GREY ;
  137.       row = n / (BCOLS*2) ;
  138.       column = (n - (row*BCOLS*2)) / 2 ;
  139.       portion = n & 1 ;
  140.       draw_button(row, column, portion, NORMAL) ;
  141.     }                    
  142. }
  143.  
  144.  
  145. handle_down_event(type)
  146. int type ;
  147. {
  148.   x = curx ;
  149.   y = cury ;
  150.   if (!down)
  151.     {
  152.       if (pending_op == '?')
  153.         {
  154.           down = type ;
  155.           return ;
  156.         }
  157.       for (row = 0; row < BROWS; row++)
  158.         for (column = 0; column < BCOLS; column++)
  159.           if ((x > (column*(BWIDTH+BGAP)+BBORDER)) &&
  160.               (x < (column*(BWIDTH+BGAP)+BBORDER+BWIDTH)) &&
  161.               ((y - DISPLAY) > (row*(BHEIGHT+BGAP)+BBORDER)) &&
  162.               ((y - DISPLAY) < (row*(BHEIGHT+BGAP)+BBORDER+BHEIGHT)))
  163.             {
  164.               portion = (y - DISPLAY - BBORDER -
  165.                          (row*(BHEIGHT+BGAP))) / (BHEIGHT/2) ;
  166.               inv_but(row, column, portion, INVERTED) ;
  167.               down = type ;
  168.               return ;
  169.             }
  170.     } 
  171. }
  172.  
  173.  
  174. handle_menu_selection(menu, item)   /* Process right button menu selection. */
  175. int menu, item ;
  176. {
  177.   pending = validmenu[menu] ;
  178.   current = num_names[item-1][0] ;
  179.   do_pending() ;
  180.   down = 0 ;
  181.   inv_but(row, column, portion, NORMAL) ;
  182. }
  183.  
  184.  
  185. inv_but(row, column, portion, state)
  186. int row, column, portion ;
  187. enum but_state state ;
  188. {
  189.   int n ;
  190.  
  191.   n = row*BCOLS*2 + column*2 + portion ;
  192.   if (pending_op != '?')
  193.     {
  194.       if (state == NORMAL)
  195.         if (iscolor) color = buttons[n].color ;
  196.         else color = (portion) ? BLACK : WHITE ;
  197.       if (state == INVERTED)
  198.         color = (portion) ? WHITE : BLACK ;
  199.       fillbox(column*(BWIDTH+BGAP)+BBORDER+6,
  200.               DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+5+(portion*22),
  201.               32, 19, portion, color) ;
  202.       but_text(row, column, portion, state) ;
  203.     }
  204. }
  205.  
  206.  
  207. make_canvas(toggle)
  208. int toggle ;
  209. {
  210.   if (toggle) tstate = !tstate ;
  211.   color = (iscolor) ? GREY : WHITE ;
  212.   clear_canvas(KEYCANVAS, color) ;
  213.   if (iscolor) color_area(0, 0, TWIDTH, DISPLAY, WHITE) ;
  214.   drawline(0, DISPLAY, TWIDTH, DISPLAY) ;
  215.   for (row = 0; row < BROWS; row++)
  216.     for (column = 0; column < BCOLS; column++)
  217.       for (portion = 0; portion < 2; portion++)
  218.         draw_button(row, column, portion, NORMAL) ;
  219.  
  220.   set_item(BASEITEM,base_str[(int) base]) ;
  221.   set_item(DISPLAYITEM, display) ;
  222.   set_item(NUMITEM, dtype_str[(int) dtype]) ;
  223.   set_item(OPITEM, items[(int) OPITEM].text) ;
  224.   set_item(TTYPEITEM,ttype_str[(int) ttype]) ;
  225.   set_item(HYPITEM, (hyperbolic) ? "HYP " : "    ") ;
  226.   set_item(INVITEM, (inverse) ? "INV " : "    ") ;
  227.   make_registers() ;
  228. }
  229.  
  230.  
  231. make_menus()      /* Create the popup menus used by the graphics versions. */
  232. {
  233.  
  234. /*  There are nine popup menus. These are associated with the following keys:
  235.  *
  236.  *  ACC  - range of possible accuracies (0 - 9).
  237.  *
  238.  *  CON  - constant values plus associated comments, if present.
  239.  *
  240.  *  EXCH - list of register numbers (0 - 9).
  241.  *
  242.  *  FUN  - function definitions plus associated comments, if present.
  243.  *
  244.  *  HELP - contains all the keys in the calculator.
  245.  *
  246.  *   <   - range of possible left shift values (0 - 9).
  247.  *
  248.  *   >   - range of possible right shift values (0 - 9).
  249.  *
  250.  *  RCL  - list of register numbers (0 - 9).
  251.  *
  252.  *  STO  - list of register numbers (0 - 9).
  253.  */
  254.  
  255.   create_menu(M_ACC) ;     /* Accuracies. */
  256.   create_menu(M_CON) ;     /* Constant definitions. */
  257.   create_menu(M_EXCH) ;    /* Register exchange. */
  258.   create_menu(M_FUN) ;     /* Function definitions. */
  259.   create_menu(M_LSHIFT) ;  /* Left shift. */
  260.   create_menu(M_RSHIFT) ;  /* Right shift. */
  261.   create_menu(M_RCL) ;     /* Register recall. */
  262.   create_menu(M_STO) ;     /* Register store. */
  263. }
  264.  
  265.  
  266. make_registers()           /* Calculate memory register frame values. */
  267. {
  268.   char line[MAXLINE] ;     /* Current memory register line. */
  269.   int n ;
  270.  
  271.   if (!rstate) return ;
  272.   clear_canvas(REGCANVAS, WHITE) ;
  273.   drawtext(15, 20, REGCANVAS, NFONT, BLACK, "Memory Registers") ;
  274.   for (n = 0; n < MAXREGS; n++)
  275.     {
  276.       SPRINTF(line, "%1d   %s", n, make_number(mem_vals[n])) ;
  277.       drawtext(15, 40+15*n, REGCANVAS, NFONT, BLACK, line) ;
  278.     }
  279. }
  280.  
  281.  
  282. process_event(type)       /* Process this event. */
  283. int type ;
  284. {
  285.   int i, n ;
  286.  
  287.   n = row*BCOLS*2 + column*2 + portion ;
  288.   switch (type)
  289.     {
  290.       case CFRAME_REPAINT  : make_canvas(0) ;
  291.                              set_item(BASEITEM, base_str[(int) base]) ;
  292.                              set_item(TTYPEITEM, ttype_str[(int) ttype]) ;
  293.                              break ;
  294.       case EXIT_WINDOW     : if (pending_op != '?')
  295.                                if (n >= 0 && n <= (NOBUTTONS*2))
  296.                                  {
  297.                                    draw_button(row, column, portion, NORMAL) ;
  298.                                    if (!portion)
  299.                                      draw_button(row, column, 1, NORMAL) ;
  300.                                  }
  301.                              down = 0 ;
  302.                              break ;
  303.       case KEYBOARD        : nextc = cur_ch ;
  304.                              for (n = 0; n < TITEMS; n++)
  305.                                if (nextc == buttons[n].value) break ;
  306.                              if (n == TITEMS) return ;
  307.                              row = n / (BCOLS * 2) ;
  308.                              column = (n - (row * BCOLS * 2)) / 2 ;
  309.                              portion = n & 1 ;
  310.                              process_item(n) ;
  311.                              break ;
  312.       case LEFT_DOWN       :
  313.       case MIDDLE_DOWN     :
  314.       case RIGHT_DOWN      : handle_down_event(type) ;
  315.                              if (type == RIGHT_DOWN) get_menu_value() ;
  316.                              break ;
  317.       case LEFT_UP         :
  318.       case MIDDLE_UP       :
  319.       case RIGHT_UP        : x = curx ;
  320.                              y = cury ;
  321.                              if ((type == LEFT_UP && down == LEFT_DOWN) ||
  322.                                  (type == MIDDLE_UP && down == MIDDLE_DOWN) ||
  323.                                  (type == RIGHT_UP && down == RIGHT_DOWN))
  324.                                {
  325.                                  if (pending_op != '?' && n <= (NOBUTTONS*2))
  326.                                    inv_but(row, column, portion, NORMAL) ;
  327.                                  down = 0 ;
  328.                                  if (n >= 0 && n <= (NOBUTTONS*2))
  329.                                    process_item(n) ;
  330.                                }
  331.                              break ;
  332.       case RFRAME_REPAINT  : make_registers() ;
  333.                              break ;
  334.       case TAKE_FROM_SHELF : handle_selection() ;
  335.                              if (issel)
  336.                                for (i = 0 ; i < strlen(selection); i++)
  337.                                  for (n = 0; n < TITEMS; n++)
  338.                                    if (selection[i] == buttons[n].value)
  339.                                      {
  340.                                        process_item(n) ;
  341.                                        break ;
  342.                                      }
  343.                              break ;
  344.       case PUT_ON_SHELF    : get_display() ;
  345.                              break ;
  346.       case DIED            : exit(0) ;
  347.     }                           
  348. }
  349.  
  350.  
  351. set_item(itemno, str)
  352. enum item_type itemno ;
  353. char *str ;
  354. {
  355.   enum font_type font ;
  356.   char *old_text ;
  357.   int x, y ;
  358.  
  359.   old_text = items[(int) itemno].text ;
  360.   if (itemno == DISPLAYITEM)
  361.     x = 5+(MAX_DIGITS - strlen(old_text))*nfont_width ;
  362.   else x = items[(int) itemno].x ;
  363.   y = items[(int) itemno].y ;
  364.   font = items[(int) itemno].font ;
  365.   old_text = items[(int) itemno].text ;
  366.   drawtext(x, y, KEYCANVAS, font, WHITE, old_text) ;
  367.  
  368.   if (itemno == DISPLAYITEM) x = 5+(MAX_DIGITS - strlen(str))*nfont_width ;
  369.  
  370.   drawtext(x, y, KEYCANVAS, font, BLACK, str) ;
  371.   STRCPY(items[(int) itemno].text, str) ;
  372. }
  373.